﻿////////////////////////////////////////////////////////////////////////////
//  Copyright 2009 - 2011 Zach Snow                                       //
////////////////////////////////////////////////////////////////////////////
//  This file is part of WindowsWhere.                                    //
//                                                                        //
//  WindowsWhere is free software: you can redistribute it and/or modify  //
//  it under the terms of the GNU General Public License as published by  //
//  the Free Software Foundation, either version 3 of the License, or     //
//  (at your option) any later version.                                   //
//                                                                        //
//  WindowsWhere is distributed in the hope that it will be useful,       //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of        //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
//  GNU General Public License for more details.                          //
//                                                                        //
//  You should have received a copy of the GNU General Public License     //
//  along with WindowsWhere.  If not, see <http://www.gnu.org/licenses/>. //
////////////////////////////////////////////////////////////////////////////
// This file was derived from code by Paul Welter; see                    //
// http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx        //
////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Drawing;

namespace WindowsWhere
{
  /// <summary>
  /// An XML serializable dictionary.  Originally written by Paul Welter;
  /// see http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx
  /// </summary>
  /// <typeparam name="TKey">key type</typeparam>
  /// <typeparam name="TValue">value type</typeparam>
  [XmlRoot("Dictionary")]
  public class SerializableDictionary<TKey, TValue>
    : Dictionary<TKey, TValue>, IXmlSerializable
  {
    #region Constructors
    public SerializableDictionary()
      : base()
    {
    }
    
    public SerializableDictionary(IDictionary<TKey, TValue> dictionary)
      : base(dictionary)
    {
    }

    public SerializableDictionary(IEqualityComparer<TKey> comparer)
      : base(comparer)
    {
    }

    public SerializableDictionary(int capacity)
      : base(capacity)
    {
    }

    public SerializableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
      : base(dictionary, comparer)
    {
    }

    public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer)
      : base(capacity, comparer)
    {
    }

    protected SerializableDictionary(SerializationInfo info, StreamingContext context)
      : base(info, context)
    {
    }
    #endregion

    #region IXmlSerializable Members
    public System.Xml.Schema.XmlSchema GetSchema()
    {
      return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
      XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
      XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

      bool wasEmpty = reader.IsEmptyElement;
      reader.Read();

      if (wasEmpty)
        return;

      while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
      {
        reader.ReadStartElement("Item");

        reader.ReadStartElement("Key");
        TKey key = (TKey)keySerializer.Deserialize(reader);
        reader.ReadEndElement();

        reader.ReadStartElement("Value");
        TValue value = (TValue)valueSerializer.Deserialize(reader);
        reader.ReadEndElement();

        this.Add(key, value);

        reader.ReadEndElement();
        reader.MoveToContent();
      }
      reader.ReadEndElement();
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
      XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
      XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

      foreach (TKey key in this.Keys)
      {
        writer.WriteStartElement("Item");

        writer.WriteStartElement("Key");
        keySerializer.Serialize(writer, key);
        writer.WriteEndElement();

        writer.WriteStartElement("Value");
        TValue value = this[key];
        valueSerializer.Serialize(writer, value);
        writer.WriteEndElement();

        writer.WriteEndElement();
      }
    }
    #endregion
  }
}
